//
//  ForceFieldTests.m
//  ForceFieldTests
//
//  Created by Roxanne Brittain on 11/15/11.
//  Copyright (c) 2011 Digifit. All rights reserved.
//

#import "ForceFieldTests.h"

@implementation ForceFieldTests

- (void)setUp
{
    [super setUp];
    
    world = new FFWorld();
}

- (void)tearDown
{
    world = nil;
    [super tearDown];
}

//white box?

- (void)addObject
{
    [self setUp];
    world->addNewObject();
    STAssertEquals(world->objectCount(), 1, @"one object after insert.");
    [self tearDown];
}

- (void)clearObjects
{
    [self setUp];
    for (int i=0; i<20; i++) world->addNewObject();
    world->clearObjects();
    
    STAssertEquals(world->objectCount(), 0, @"added");
    
    [self tearDown];
}

//black box?

- (void)testMomentumConservation
{
    [self setUp];
    FFObject *o1 = world->addNewObject().object;
    FFObject *o2 = world->addNewObject().object;
    o1->setVelocity(1, 1);
    o2->setVelocity(-2, -2);
    
    float initialMomentumX = .5*pow(o1->getXVelocity(), 2) + .5*pow(o2->getXVelocity(), 2);
    float initialMomentumY = .5*pow(o1->getYVelocity(), 2) + .5*pow(o2->getYVelocity(), 2);
    
    FFCollisionHandler *handler = new FFCollisionHandler();
    handler->handleCollision(o1, o2);
    
    float finalMomentumX = .5*pow(o1->getXVelocity(), 2) + .5*pow(o2->getXVelocity(), 2);
    float finalMomentumY = .5*pow(o1->getYVelocity(), 2) + .5*pow(o2->getYVelocity(), 2);
    
    STAssertEquals(initialMomentumX, finalMomentumX, @"x momentum matches");
    STAssertEquals(initialMomentumY, finalMomentumY, @"y momentum matches");
    [self tearDown];
}

- (void)testFramerate
{
    
    [self setUp];
    int targetFramesPerSecond = 100;
    float s = 1/targetFramesPerSecond;
    
    for (int i=0; i<10; i++) {
        FFObject *obj = world->addNewObject().object;
        obj->randomizeValues(320, 480);
    }
    
    NSDate *startTime = [NSDate date];
    for (int i=0; i<targetFramesPerSecond; i++) world->refreshWithSeconds(s);
    float duration = -1*[startTime timeIntervalSinceNow];
    
    STAssertTrue(duration<1, [NSString stringWithFormat:@"duration: %.2f", duration]);
    [self tearDown];
}

- (void)testElectrostaticForce
{
    [self setUp];
    FFObject *o1 = world->addNewObject().object;
    FFObject *o2 = world->addNewObject().object;
    o1->setCharge(1);
    o2->setCharge(1);
    
    FFFieldHandler *handler = new FFFieldHandler();
    float magnitude = handler->calculateAndApplyForces(o1, o2);
    float distance = distanceBetweenObjects(o1, o2);
    
    float shouldbe = kPropConstant/pow(distance, 2);
    
    STAssertEquals(shouldbe, magnitude, @"electrostatic force");
    [self tearDown];
}

@end
